/**
 * 身份证验证Util
 */
export class NumberUtil {

    /** 手机号码 */
    static isPhoneNumber(str: string) {
        if(!str) return false;
        return /^1[3|4|5|6|7|8][0-9]{9}$/.test(str);
    }

    /** 密码以字母开头，长度在6~18之间，只能包含字母、数字和下划线 */
    static isPWD(str: string) {
        if(!str) return false;
        return /^[a-zA-Z]\w{5,17}$/.test(str)
    }

    /** 邮箱 */
    static isEMAIL(str: string) {
        if(!str) return false;
        return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
    }

    /** 全数字 */
    static isAllDigital(str: string) {
        if(!str) return false;
        return /^[0-9]*$/.test(str);
    }

    /**
     * 校验是否是4位数字
     */
    static is4Digtal(str: string): boolean {
        if(!str) return false;
        return /^\d{4}$/.test(str);
    }


    /** 去掉小数点之后多余的0 */
    static subZeroAndDot(money: number): string {
        if(!money) return 0;
        if(money === 0) return 0;
        let s = String.valueOf(money);
        if (s.indexOf(".") > 0) {
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }

    /**
     * 以344格式格式化手机号码
     */
    static getFormatPhone(phone: string): string {
        if (!phone) return "";
        if (!NumberUtil.isPhoneNumber(phone)) return phone;
        return phone.substring(0, 3) + " " + phone.substring(3, 7) + " " + phone.substring(7, 11);
    }


    /**
     * 隐藏手机号码中间四位
     */
    static getSecretPhoneNumber(phoneStr: string): string {
        if (!phoneStr) return "";
        return phoneStr.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
    }

    /**
     * 隐藏银行卡除最后4位
     */
    static getSecretIdCard(idCard: string): string {
        if (!idCard) return "";
        return idCard.replace(/^(\d{4})\d+(\d{4})$/, '**** **** **** $2');
    }


    /**
     * 校验身份证号码
     */
    static isIDCardValid(value) {
        if (!NumberUtil.checkIdCardDate(value)) return false;
        return (value.length === 18 && NumberUtil.isIDCard18(value));
    }

    /**
     * 校验18位身份证号码
     */
    static isIDCard18(value) {
        if (value === null || typeof value === 'undefined' || value.length !== 18) return false;
        if (!value.match("[\\d]+[X]?")) return false;

        let code = "10X98765432";
        let weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1];

        let nSum = 0;
        for (let i = 0; i < 17; ++i) {
            nSum += parseInt(value.charAt(i) - '0') * weight[i];
        }

        let nCheckNum = nSum % 11;
        let chrValue = value.charAt(17);
        let chrCode = code.charAt(nCheckNum);
        if (chrValue === chrCode) return true;
        if (nCheckNum === 2 && (chrValue + ('a' - 'A') === chrCode)) return true;
        return false;
    }


    /**
     * 校验身份证的日期格式是否正确
     */
    static checkIdCardDate(value) {
        if (value === null || typeof value === 'undefined' || !value.match("[\\d]+[X]?")) {
            return false;
        }

        let nLen = value.length;
        if (nLen !== 15 && nLen !== 18) return false;

        let date = null;
        if (nLen === 15) {
            date = "19" + value.substring(6, 12);
        } else {
            date = value.substring(6, 14);
        }
        return NumberUtil.checkDate8(date);
    }

    /**
     * 校验8位日期
     */
    static checkDate8(date) {
        if (date.length !== 8) return false;
        try {
            let year = parseInt(date.substring(0, 4));
            let month = parseInt(date.substring(4, 6));
            let day = parseInt(date.substring(6, 8));
            return NumberUtil.checkDate(year, month, day);
        } catch (e) {
        }
        return false;
    }

    static checkDate(nYear, nMonth, nDay) {
        if (nYear < 1800 || nMonth < 1 || nMonth > 12 || nDay < 1 || nDay > 31)
            return false;

        if (nMonth === 2) {
            if (nDay > 29) return false;
            if (nDay === 29 && !((nYear % 4 === 0 && nYear % 100 !== 0) || nYear % 400 === 0))
                return false;
            return true;
        }

        if (nMonth === 4 || nMonth === 6 || nMonth === 9 || nMonth === 11) {
            if (nDay < 31) return true;
            else return false;
        }
        return true;
    }

}
